/**
 * Copyright (c) 2011-2016, hubin (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.beone;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.beone.generator.WebAutoGenerator;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/**
 * @title  代码生成器演示
 * @author 覃球球
 * @date 2018-10-31 长笛龙吟
 */
public class WorkshopMysqlGenerator {

    private static final String template_path = "/templates/vm/";

    private static ResourceBundle rb = null;

    static{
        loadConfigFile();
    }

    public static void loadConfigFile(){
        rb = ResourceBundle.getBundle("mybatis-plus-generator");
    }

    /**
     * <p>
     * MySQL 生成演示
     * </p>
     */
    public static void main(String[] args) {
        // 自定义需要填充的字段
//        List<TableFill> tableFillList = new ArrayList<>();
//        tableFillList.add(new TableFill("ASDD_SS", FieldFill.INSERT_UPDATE));



        // 代码生成器
        AutoGenerator mpg = initAutoGeneratorConfig();
        mpg.setCfg(new InjectionConfig() { // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
            @Override
            public void initMap() {
               /* Map<String, Object> map = new HashMap<>();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                this.setMap(map);*/
                }
            }.setFileOutConfigList(getFileOutCOnfig("app"))
        );
        // 执行生成
        mpg.execute();

        // 打印注入设置，这里演示模板里面怎么获取注入内容【可无】
        //System.err.println(" --- " + mpg.getCfg().getMap().get("abc"));
    }

    /**
     * @param type  生成方式  web   app【默认main函数启动生成】
     * @return
     */
    public static List<FileOutConfig> getFileOutCOnfig(String type){
        ArrayList<FileOutConfig>  files = new ArrayList<FileOutConfig>();
        files.add(new MapperXmlFileOutConfig("/templates/vm/mapper.xml.vm"));
        String pageUrl = "/templates/vm/views/" + rb.getString("ui.template");

        if("web".equals(type)){
            files.add(new PageFileOutConfig(pageUrl + "/index_web.html.vm", "index"));
            files.add(new PageFileOutConfig(pageUrl + "/form_web.html.vm", "form"));
        }else if("app".equals(type)){
            files.add(new PageFileOutConfig(pageUrl + "/index.html.vm", "index"));
            files.add(new PageFileOutConfig(pageUrl + "/form.html.vm", "form"));
        }
        return files;
    }

    public static AutoGenerator initAutoGeneratorConfig(){

        // 代码生成器
        AutoGenerator mpg = new WebAutoGenerator()
            .setGlobalConfig(getGlobalConfig())// 全局配置
            .setDataSource(getDataSourceConfig())// 数据源配置
            .setStrategy(getStrategyConfig())// 策略配置
            .setPackageInfo( new PackageConfig() // 包配置
                    .setModuleName(rb.getString("module.name"))
                    .setParent(rb.getString("module.parent.pkg"))// 自定义包路径
                    .setController("controller")// 这里是控制器包名，默认 web
                    .setEntity("entity")
                    .setMapper("mapper")
                    .setService("service")
                    .setServiceImpl("service.impl")
            ).setTemplate(
                    // 关闭默认 xml 生成，调整生成 至 根目录
                    new TemplateConfig().setXml(null)
                            // 自定义模板配置，模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
                            // 至您项目 src/main/resources/template 目录下，模板名称也可自定义如下配置：
                            .setController(template_path + "controller.java.vm")
                            .setEntity(template_path + "entity.java.vm")
                            .setMapper(template_path + "mapper.java.vm")
                            //.setXml(template_path + "mapper.xml.vm")
                            .setService(template_path + "service.java.vm")
                            .setServiceImpl(template_path + "serviceImpl.java.vm")
            );
        return mpg;
    }


    public static DataSourceConfig getDataSourceConfig() {
        return new DataSourceConfig()
                .setDbType(DbType.MYSQL)// 数据库类型
                .setTypeConvert(new MySqlTypeConvert() {
                    // 自定义数据库表字段类型转换【可选】
                    @Override
                    public DbColumnType processTypeConvert(String fieldType) {
                        //System.out.println("转换类型：" + fieldType);
                        // if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
                        //    return DbColumnType.BOOLEAN;
                        // }
                        return super.processTypeConvert(fieldType);
                    }
                })
                .setDriverName(rb.getString("db.driverName"))
                .setUsername(rb.getString("db.username"))
                .setPassword(rb.getString("db.password"))
                .setUrl(rb.getString("db.url"));
    }


    public static GlobalConfig getGlobalConfig() {
        return new GlobalConfig()
                .setOutputDir(rb.getString("output.dir"))//输出目录
                .setFileOverride(true)// 是否覆盖文件
                .setActiveRecord(false)// 开启 activeRecord 模式
                .setEnableCache(false)// XML 二级缓存
                .setBaseResultMap(true)// XML ResultMap
                .setBaseColumnList(true)// XML columList
                //.setKotlin(true) 是否生成 kotlin 代码
                .setAuthor(rb.getString("author"))
                // 自定义文件命名，注意 %s 会自动填充表实体属性！
                .setMapperName("%sMapper")
                .setXmlName("%sMapper")
                .setServiceName("%sService")
                .setServiceImplName("%sServiceImpl")
                .setControllerName("%sController");

    }

    public static StrategyConfig getStrategyConfig(){
        StrategyConfig config = new StrategyConfig();
                // .setCapitalMode(true)// 全局大写命名
                // .setDbColumnUnderline(true)//全局下划线命名
        String tablePrefix = rb.getString("table.prefix");
        if(StringUtils.isNotBlank(tablePrefix)){
            config.setTablePrefix(tablePrefix.split(","));// 此处可以修改为您的表前缀
        }
        //config.setTablePrefix(new String[]{"tbl_", "mp_"});// 此处可以修改为您的表前缀
        config.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略

        String includeTables = rb.getString("include.tables");
        if(StringUtils.isNotBlank(includeTables)){
            config.setInclude(includeTables.split(",")); // 需要生成的表
        }
        //config.setInclude(new String[] { "tbl_user","tbl_user_role" }); // 需要生成的表
                // .setExclude(new String[]{"test"}) // 排除生成的表
                // 自定义实体父类
        //继承Mapper、Service、Controller父类包名
        String  parent_package_name = rb.getString("parent.package.name");

        //config.setInclude(new String[] { "tbl_user","tbl_user_role" }); // 需要生成的表
        // .setExclude(new String[]{"test"}) // 排除生成的表
        // 自定义实体父类
        config.setSuperEntityClass(parent_package_name + ".common.BaseModel");
        // 自定义实体，公共字段
        //.setSuperEntityColumns(new String[]{"test_id"})
        //.setTableFillList(tableFillList)
        // 自定义 controller 父类
        config.setSuperControllerClass(parent_package_name + ".SuperController");
        config.setSuperMapperClass(parent_package_name + ".SuperMapper");
        // 自定义 service 父类
        config.setSuperServiceClass(parent_package_name + ".ISuperService");
        // 自定义 service 实现类父类
        config.setSuperServiceImplClass(parent_package_name + ".SuperServiceImpl");
        // 自定义 controller 父类
        // .setSuperControllerClass("com.baomidou.demo.TestController")
        // 【实体】是否生成字段常量（默认 false）
        // public static final String ID = "test_id";
        // .setEntityColumnConstant(true)
        // 【实体】是否为构建者模型（默认 false）
        // public User setName(String name) {this.name = name; return this;}
        // .setEntityBuilderModel(true)
        // 【实体】是否为lombok模型（默认 false）<a href="https://projectlombok.org/">document</a>
        // .setEntityLombokModel(true)
        // Boolean类型字段是否移除is前缀处理
        // .setEntityBooleanColumnRemoveIsPrefix(true)
        // config.setRestControllerStyle(true)
        // .setControllerMappingHyphenStyle(true)
        return config;
    }

    /**
     * Xml 模板
     */
    public static class  MapperXmlFileOutConfig extends FileOutConfig{
        public MapperXmlFileOutConfig(String xmlTemplatePath){
            super(xmlTemplatePath);
        }

        // 自定义输出文件目录
        @Override
        public String outputFile(TableInfo tableInfo) {
            String dir = rb.getString("output.dir.mapper");
            return dir + tableInfo.getEntityName() + "Mapper.xml";
        }
    }

    /**
     * Page 模板
     */
    public static class PageFileOutConfig extends FileOutConfig{
        private String pageName;
        public PageFileOutConfig(String xmlTemplatePath, String pageName){
            super(xmlTemplatePath);
            this.pageName = pageName;
        }

        // 自定义输出文件目录
        @Override
        public String outputFile(TableInfo tableInfo) {
            String dir = rb.getString("output.dir.page");
            return dir + tableInfo.getEntityPath() + "/" + pageName + ".html";
        }
    }
}
